package net;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Server {
	private Logger logger = Logger.getLogger(Server.class.getName());

	private int port;
	
	private Set<Client> clientPool = new HashSet<Client>();

	private ServerSocket serverSocket;
	
	public class Client{
		Socket socket ;
		
		private OutputStream outputStream;
		private InputStream inputStream;
		
		private BufferedWriter writer;
		private BufferedReader reader;		
		
		Client(Socket socket) throws IOException{
			this.socket = socket;
			
			outputStream = socket.getOutputStream();
			inputStream = socket.getInputStream();
			
			writer = new BufferedWriter(new OutputStreamWriter(outputStream));
			reader = new BufferedReader(new InputStreamReader(inputStream));
			
			logger.log(Level.INFO, "Client Connected");
		}

		public void close() throws IOException{
			writer.close();
			reader.close();
			outputStream.close();
			inputStream.close();
		}
		
		public OutputStream getOutputStream() {
			return outputStream;
		}

		public InputStream getInputStream() {
			return inputStream;
		}

		public BufferedWriter getWriter() {
			return writer;
		}

		public BufferedReader getReader() {
			return reader;
		}
	}
	
	
	public Server(int port) throws UnknownHostException, IOException {
		try {
		    serverSocket = new ServerSocket(port);
		} catch (IOException e) {
			logger.log(Level.INFO, "Could not listen on port: "+port);
		    throw e;
		}
	}
	
	public Client wait4Client() throws IOException{
		System.out.println("Server Initialized");
		Socket clientSocket = null;
		try {
		    clientSocket = serverSocket.accept();
		    Client client = new Client(clientSocket);
		    clientPool.add(client);
		    return client;
		} catch (IOException e) {
			logger.log(Level.INFO, "Accept failed: "+port);
			throw e;
		}
	}

	public Set<Client> getClientPool() {
		return clientPool;
	}
	
	public void close() throws IOException{
		serverSocket.close();
	}
}
